﻿using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media.Media3D;

namespace Visualizer
{
    /// <summary>
    /// One way converter from <see cref="System.Windows.Media.Media3D.Point3D"/> to String,
    /// with two decimal places
    /// </summary>
    public class Point3DToStringConverter : IValueConverter
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="Point3DToStringConverter"/> class.
        /// </summary>
        public Point3DToStringConverter() {

        }

        /// <summary>
        /// Converts a Point3D to String.
        /// </summary>
        /// <param name="value">A <c>Point3D</c> (The value that is produced by the binding target).</param>
        /// <param name="targetType"><c>typeof(String)</c> oder <c>typeof(Object)</c> (The type to convert to).</param>
        /// <param name="parameter">Not used (The converter parameter to use).</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>
        /// String representation of the Point3D value, with two decimal places.
        /// </returns>
        /// <exception cref="System.NotSupportedException">targetType is not <c>typeof(String)</c></exception>
        /// <exception cref="System.NotSupportedException">value is not a <c>Point3D</c></exception>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            if (!targetType.Equals(typeof(String))) {
                if (!targetType.Equals(typeof(Object))) {
                    //return null;
                    throw new NotSupportedException("Conversion back to " + targetType.Name + "not supported, only to String.");
                }
            }
            if (value is Point3D) {
                Point3D source = (Point3D)value;
                IFormatProvider format;
                if (culture == null) {
                    format = CultureInfo.CurrentCulture.NumberFormat;
                }
                else {
                    format = culture.NumberFormat;
                }
                String resu = String.Format(culture, "{0:N2}, {1:N2}, {2:N2}", source.X, source.Y, source.Z);
                return resu;
            }
            else {
                //return null;
                throw new NotSupportedException("Source object (value) is not a " + typeof(Point3D).FullName);
            }
        }

        /// <summary>
        /// Converts a <c>String</c> value to a <c>Point3D</c>.
        /// </summary>
        /// <param name="value">A String (The value produced by the binding source.)</param>
        /// <param name="targetType"><see cref="System.Windows.Media.Media3D.Point3D"/> (The type of the binding target property).</param>
        /// <param name="parameter">Not used (The converter parameter to use).</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>
        /// new Point3D(0,0,0)
        /// </returns>
        /// <exception cref="System.NotSupportedException">targetType is not <c>typeof(Point3D)</c></exception>
        /// <exception cref="System.ArgumentException">value is not a String or is null.</exception>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            if (targetType != typeof(Point3D)) {
                //return null;
                throw new NotSupportedException("Conversion to " + targetType.Name + "not supported, only to Point3D.");
            }
            Point3D resu = new Point3D();
            if (value == null) {
                return resu;
            }
            String val = value as String;
            if (val == null) {
                throw new ArgumentException("Value must be a String", "value");
            }
            IFormatProvider format;
            if (culture == null) {
                format = CultureInfo.CurrentCulture.NumberFormat;
            }
            else {
                format = culture.NumberFormat;
            }
            // TODO Parse String to Point3D
            return resu;
        }
    }
}
